;; Entrypoints are addresses referencing some code. They can reference native and directly
;; runnable code or a interpretable word.  In the case of directly runnable code, they are meant
;; to internal interpreter use. They can be call-able (you start its execution with a `call`
;; instruction, they return to your code with a 'ret' instruction) or jmp-able (you start it
;; with a 'jmp' instruction, they will continue to execute internal interpreter's code).

;; EBP holds the return stack top. ESP holds the data stack top.

_pushrst:                       ;Native call-able entrypoint to push ESI onto return stack
  lea ebp, [ebp-4]
  mov [ebp], esi
  ret
_poprst:                        ;Native call-able entrypoint to pop the return stack into ESI
  mov esi, [ebp]
  lea ebp, [ebp+4]
  ret

;; Words are (potentially) user-accessible sets of instructions. Every word has a entrypoint and
;; a definition (its contents). They can be run by the interpreter, can call or be called by
;; other words through the interpreter (which supports the word's code controlling the return
;; stack for proper operation) and can be referenced at a dictionary.

;; Codewords are special entrypoints used as a pointer in the beggining of the definition of
;; every word. They implement the specific interpreter code needed to execute that word.

_enter_native:                  ;Codeword for native words: words made of native machine code
  jmp esi
_leave_routine:                 ;Word to end a virtual routine
  dd _enter_native
_end_caller:                    ;Jmp-able entrypoint to end the caller routine
  call _poprst
_next_routine:                  ;Jmp-able entrypoint to end the current native routine
  call _poprst
  add esi, 4
_enter_routine:                 ;Codeword for virtual words: words made of other words entrypoints
  call _pushrst
  lodsd
  mov esi, eax
_next:                          ;Entrypoint to jump into the next word's codeword
  lodsd
  jmp eax

_halt:
  dd _enter_native
  mov eax, sys_exit
  mov ebx, 0
  int 80h

;; `_literal` word gets the value that should be the next word to be run in the current routine
;; and pushes this value at the data stack, skipping its execution.

_literal:
  dd _enter_native
  add dword [ebp], 4            ;Return stack top points at the next word to be run
  mov eax, [ebp]
  push dword [eax]
  jmp _next_routine